package com.alibaba.dingtalk.openapi.utils;


import org.apache.commons.codec.binary.Base64;

import javax.crypto.Mac;
import javax.crypto.spec.SecretKeySpec;
import java.io.UnsupportedEncodingException;
import java.net.URLEncoder;
import java.security.InvalidKeyException;
import java.security.NoSuchAlgorithmException;

/**
 * 签名帮助类
 *
 * @author kaka
 * @version v1.0
 * @date 2019/12/19 20:44
 * @since v1.0
 */
public class DingtalkSignHelper {


    /**
     * 获取签名
     * @param suiteTicket
     * @param timestamp
     * @param suiteSecret
     * @return
     * @throws NoSuchAlgorithmException
     * @throws UnsupportedEncodingException
     * @throws InvalidKeyException
     */
    public static String getSign(String suiteTicket, String timestamp, String suiteSecret) throws NoSuchAlgorithmException, UnsupportedEncodingException, InvalidKeyException {
        String stringToSign = timestamp + "\n" + suiteTicket;
        Mac mac = Mac.getInstance("HmacSHA256");
        mac.init(new SecretKeySpec(suiteSecret.getBytes("UTF-8"), "HmacSHA256"));
        byte[] signData = mac.doFinal(stringToSign.getBytes("UTF-8"));
        return new String(Base64.encodeBase64(signData));
    }

    /**
     * encoding参数使用utf-8
     * @param value
     * @param encoding
     * @return
     */
    public static String urlEncode(String value, String encoding) {
        if (value == null) {
            return "";
        }

        try {
            String encoded = URLEncoder.encode(value, encoding);
            return encoded.replace("+", "%20").replace("*", "%2A")
                    .replace("~", "%7E").replace("/", "%2F");
        } catch (UnsupportedEncodingException e) {
            throw new IllegalArgumentException("FailedToEncodeUri", e);
        }
    }

    /**
     * 获取签名并作urlEncode
     * @param suiteTicket
     * @param timestamp
     * @param suiteSecret
     * @return
     * @throws NoSuchAlgorithmException
     * @throws UnsupportedEncodingException
     * @throws InvalidKeyException
     */
    public static String getEncodeSign(String suiteTicket, String timestamp, String suiteSecret) throws NoSuchAlgorithmException, UnsupportedEncodingException, InvalidKeyException {
        return urlEncode(getSign(suiteTicket, timestamp, suiteSecret),"utf-8");
    }
}
